package com.poly.police.monitor.application.service.sys.impl;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.poly.police.monitor.application.config.UserThreadLocal;
import com.poly.police.monitor.application.mapper.sys.SysMenuMapper;
import com.poly.police.monitor.application.service.sys.ISysMenuService;
import com.poly.police.monitor.application.service.sys.ISysPermService;
import com.poly.police.monitor.common.util.ListUtils;
import com.poly.police.monitor.pojo.entity.sys.SysMenu;
import com.poly.police.monitor.pojo.validate.sys.SysMenuCreateValidate;
import com.poly.police.monitor.pojo.validate.sys.SysMenuUpdateValidate;
import com.poly.police.monitor.pojo.vo.sys.SysMenuVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 系统菜单服务实现类
 */
@Service
public class SysMenuServiceImpl implements ISysMenuService {

    @Resource
    SysMenuMapper sysMenuMapper;

    @Resource
    ISysPermService iSysPermService;

    /**
     * 根据角色ID获取菜单
     *
     * @author fzr
     * @param roleIds 角色ID
     * @return JSONArray
     */
    @Override
    public JSONArray selectMenuByRoleId(List<Long> roleIds) {
        Long adminId = UserThreadLocal.getUserId();
        List<Long> menuIds = iSysPermService.selectMenuIdsByRoleId(roleIds);

        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("menu_type", Arrays.asList("M", "C"));
        queryWrapper.eq("is_disable", 0);
        queryWrapper.orderByDesc("menu_sort");
        queryWrapper.orderByAsc("id");
        if (!adminId.equals(1)) {
            if (menuIds.size() <= 0) {
                menuIds.add(0L);
            }
            queryWrapper.in("id", menuIds);
        }

        List<SysMenu> sysMenus = sysMenuMapper.selectList(queryWrapper);

        List<SysMenuVo> lists = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            SysMenuVo vo = new SysMenuVo();
            BeanUtils.copyProperties(sysMenu, vo);
            lists.add(vo);
        }

        JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(lists));
        return ListUtils.listToTree(jsonArray, "id", "pid", "children");
    }

    /**
     * 菜单列表
     *
     * @author fzr
     * @return JSONArray
     */
    @Override
    public JSONArray list() {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("menu_sort");
        queryWrapper.orderByAsc("id");

        List<SysMenu> sysMenus = sysMenuMapper.selectList(queryWrapper);

        List<SysMenuVo> lists = new ArrayList<>();
        for (SysMenu sysMenu : sysMenus) {
            SysMenuVo vo = new SysMenuVo();
            BeanUtils.copyProperties(sysMenu, vo);

            lists.add(vo);
        }

        JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(lists));
        return ListUtils.listToTree(jsonArray, "id", "pid", "children");
    }

    /**
     * 菜单详情
     *
     * @author fzr
     * @param id 主键参数
     * @return SysMenu
     */
    @Override
    public SysMenuVo detail(Long id) {
        SysMenu sysMenu = sysMenuMapper.selectOne(new QueryWrapper<SysMenu>().eq("id", id));
        Assert.notNull(sysMenu, "菜单已不存在!");

        SysMenuVo vo  = new SysMenuVo();
        BeanUtils.copyProperties(sysMenu, vo);
        return vo;
    }

    /**
     * 新增菜单
     *
     * @author fzr
     * @param createValidate 参数
     */
    @Override
    public void add(SysMenuCreateValidate createValidate) {
        SysMenu model = new SysMenu();
        model.setPid(createValidate.getPid());
        model.setMenuType(createValidate.getMenuType());
        model.setMenuName(createValidate.getMenuName());
        model.setMenuIcon(createValidate.getMenuIcon());
        model.setMenuSort(createValidate.getMenuSort());
        model.setPerms(createValidate.getPerms());
        model.setPaths(createValidate.getPaths());
        model.setComponent(createValidate.getComponent());
        model.setSelected(createValidate.getSelected());
        model.setParams(createValidate.getParams());
        model.setIsCache(createValidate.getIsCache());
        model.setIsShow(createValidate.getIsShow());
        model.setIsDisable(createValidate.getIsDisable());
        model.setCreateTime(new Date());
        model.setUpdateTime(new Date());
        sysMenuMapper.insert(model);
    }

    /**
     * 编辑菜单
     *
     * @author fzr
     * @param updateValidate 菜单
     */
    @Override
    public void edit(SysMenuUpdateValidate updateValidate) {
        SysMenu model = sysMenuMapper.selectOne(new QueryWrapper<SysMenu>().eq("id", updateValidate.getId()));
        Assert.notNull(model, "菜单已不存在!");

        model.setMenuType(updateValidate.getMenuType());
        model.setMenuName(updateValidate.getMenuName());
        model.setMenuIcon(updateValidate.getMenuIcon());
        model.setMenuSort(updateValidate.getMenuSort());
        model.setPaths(updateValidate.getPaths());
        model.setPerms(updateValidate.getPerms());
        model.setComponent(updateValidate.getComponent());
        model.setPid(updateValidate.getPid());
        model.setSelected(updateValidate.getSelected());
        model.setParams(updateValidate.getParams());
        model.setIsCache(updateValidate.getIsCache());
        model.setIsShow(updateValidate.getIsShow());
        model.setIsDisable(updateValidate.getIsDisable());
        model.setUpdateTime(new Date());
        sysMenuMapper.updateById(model);
    }

    /**
     * 删除菜单
     *
     * @author fzr
     * @param id 主键参数
     */
    @Override
    public void del(Long id) {
        SysMenu model = sysMenuMapper.selectOne(
                new QueryWrapper<SysMenu>()
                        .select("id,pid,menu_name")
                        .eq("id", id)
                        .last("limit 1"));

        Assert.notNull(model, "菜单已不存在!");
        Assert.isNull(sysMenuMapper.selectOne(
                new QueryWrapper<SysMenu>()
                        .eq("pid", id)
                        .last("limit 1")),
                "请先删除子菜单再操作!");

        sysMenuMapper.deleteById(id);
        iSysPermService.batchDeleteByMenuId(id);
    }

}
